<?php

namespace app\common\logic;

use think\Db;
use think\Model;

class LiXinLogic extends Model
{
    private $reflectId = 0;
    public $user_id = 0;

    public function updateCalculation($user_id, $calculation, $reflectId)
    {
        $info = Db::name('member')->field('id,isReal,parentId,give_calculation')->find($user_id);
        if ($info['isReal']) {
            $before = $info['give_calculation'] + $calculation;
            $data = array(
                'reflectId' => $reflectId,
                'userId' => $info['id'],
                'type' => 1,
                'num' => $calculation,
                'after' => $info['give_calculation'],
                'before' => $before,
                'desc' => '赠送',
                'createTime' => date("Y-m-d H:i:s"),
                'updateTime' => date("Y-m-d H:i:s"),
            );
            Db::startTrans();
            $res = Db::name('calculationlog')->insertGetId($data);
            $userRes = Db::name('member')->where(['id' => $info['id']])->update(['give_calculation' => $before]);

            if ($res && $userRes) {
                Db::commit();
                if ($info['parentId']) {
                    $this->updateCalculation($info['parentId'], $calculation, $reflectId);
                }
            } else {
                Db::rollback();
            }
        }
        return false;

    }

    /**
     * 实名注册赠送渔船
     */
    public function realGivePrize($user_id)
    {
        $miners = Db::name('world_miner')->where(['type' => 2])->select();
        $config = Db::name('world_system')->where(['inc_type' => 'miner_basic','name' => 'able_give_number'])->value('value');

        foreach ($miners as $k => $va) {
            $count = Db::name('user_miner')->where(['type' => 3])->count();
            if ($config > $count) {
                // 仍有数量可赠送
                $minerData = [
                    'sn' => $this->getMinerSn(),
                    'user_id'=>$user_id,
                    'add_time' => time(),
                    'invalid_time' => time()+$va['scrap_days']*3600,
                    'all_profit' => $va['scrap_days']*$va['release'],
                    'receive'=>0,
                    'receive_time'=>time(),
                    'calculation'=>$va['miner_size'],
                    'miner_id'=>$va['miner_id'],
                    'type' => 3
                ];
                $userMinerRes = Db::name('user_miner')->insertGetId($minerData);
            } else {
                return false;
            }
        }
    }

    /**
     * 动态奖  推广奖
     * @param  $user_id 收益用户ID
     */
    public function recommendPrize($user_id)
    {
        $user = Db::name('member')->field('id,parentId,isReal')->where(['id' => $user_id])->find();
        if ($user['isReal'] != 1) {
            if ($user['parentId']) {
                $this->recommendPrize($user['parentId']);
            }
            return false;
        }
        // 获取奖项设置
        $configs = Db::name('world_system')->field('name,value')->where(['inc_type' => 'recommend_prize'])->select();
        foreach ($configs as $k => $va) {
            $config[$va['name']] = $va['value'];
        }
        unset($configs);

        // 校验开关
        if ($config['switch']) {
            $config = unserialize($config['prize']);
            krsort($config);

            $leader = Db::name('member')->field('id,path,parentId,isReal')->where(['id' => $user['parentId']])->find();
            if ($leader['isReal'] != 1) {
                return false;
            }
            // 获取直推人数
            $count = Db::name('member')->where(['parentId' => $leader['id'], 'isReal' => 1])->count();

            foreach ($config as $k => $va) {

                // 校验直推人数通过
                if ($count < $va['first_leader']) {
                    continue;
                }
                if ($va['team']) {
                    if ($leader['path']) {
                        $path = $leader['path'].','.$leader['id'];
                    } else {
                        $path = $leader['id'];
                    }

                    $team = $this->getTeam($path);
                    if ($team < $va['team']) {
                        continue;
                    }
                }
                $log = Db::name('givelog')
                        ->where([
                            'user_id' => $leader['id'],
                            'recommend_number' => $va['first_leader'],
                            'team' => $va['team'],
                            'miner_id' => $va['miner']
                            ])
                        ->find();

        // dump(Db::name('givelog')->getLastSql());
                if ($log) {
                    continue ;
                }
        // dump($va);

                $miner = Db::name('world_miner')->find($va['miner']);
                // 执行奖励
                for ($i=0; $i < $va['number']; $i++) {
                    Db::startTrans();
                    // 校验通过 奖励渔船
                    $minerData = [
                        'sn' => $this->getMinerSn(),
                        'user_id'=>$leader['id'],
                        'add_time' => time(),
                        'invalid_time' => time()+$miner['scrap_days']*3600,
                        'all_profit' => $miner['scrap_days']*$miner['release'],
                        'receive'=>0,
                        'receive_time'=>time(),
                        'calculation'=>$miner['miner_size'],
                        'miner_id'=>$miner['miner_id'],
                        'type' => 2
                    ];
                    $userMinerRes = Db::name('user_miner')->insertGetId($minerData);

                    $givelog = [
                        'user_id' => $leader['id'],
                        'to_user_id' => $this->user_id,
                        'user_miner_id' => $userMinerRes,
                        'recommend_number' => $va['first_leader'],
                        'miner_id' => $va['miner'],
                        'team' => $va['team'],
                        'add_time' => time(),
                    ];
                    $givelogRes = Db::name('givelog')->insertGetId($givelog);
                    if ($userMinerRes && $givelogRes) {
                        // dump($user);
                        Db::commit();
                    } else {
                        Db::rollback();
                    }
                }
                break;

            }
            if ($user['parentId']) {
                $this->recommendPrize($user['parentId']);
            }
            return false;

        }
    }

    /**
     * 分销
     * @param  $miner 矿池钱包
     * @return       奖项情况
     */
    public function distribuParent($parentId, $profit, $miner_id)
    {
        $leader = Db::name('member')->field('id,parentId,isReal,miner,kj_all_token,level,all_receive')->where(['id' => $parentId])->find();
        if (!$leader) {return ;}
        if ($leader['isReal'] != 1) {$this->distribuParent($leader['parentId'], $profit, $miner_id);}

        //上级会获得收益的30%
        $receive = $profit * 0.3;
        //判断用户矿机是否满足收益，如果不是，返回
        $after = $leader['kj_all_token'] - $receive;
        if ($after >= 0){
            $userData = [
                'miner' => $leader['miner'] + $receive,
                'kj_all_token' => ($leader['kj_all_token'] - $receive) < 0 ? 0 : ($leader['kj_all_token'] - $receive),
                'all_receive' => $leader['all_receive'] + $receive
            ];
            $userRes = Db::name('member')->where(['id' => $parentId])->update($userData);
            //减少矿机表里面的token
            $userMiner = Db::name('user_miner')->where(['user_id' => $parentId])->find();
            $after_kj_token = ($userMiner['kj_token'] - $receive) < 0 ? 0 : ($userMiner['kj_token'] - $receive);
            $res_user_miner = Db::name('user_miner')->where(['user_id' => $parentId])->update(['kj_token' => $after_kj_token]);
            $logRes = minerlog($miner_id, $leader['id'], $receive, 6, $leader['miner'], $userData['miner'],'收益奖励');
            if ($userRes && $logRes && $res_user_miner) {
                $this->distribuParent($leader['parentId'], ($profit * 0.3), $miner_id);
            }else{
                return ;
            }
        }else{
            $this->distribuParent($leader['parentId'], $profit, $miner_id);
        }

    }

    /**
     * 分销
     * @param  $miner 矿池钱包
     * @return       奖项情况
     */
    public function distribut($user_id, $minerInfo, $num = 1)
    {
        if ($num > 4) {
            return ;
        }

        $leader = Db::name('member')->field('id,parentId,isReal,miner,level')->where(['id' => $user_id])->find();
        if (!$leader) {return ;}
        if ($leader['isReal'] != 1) {$this->distribut($leader['parentId'], $minerInfo,$num);}

         // 获取奖项设置
        $configs = Db::name('distribut_system')->field('name,value')->where(['inc_type' => 'prize', 'level_id' => $leader['level']])->select();
        foreach ($configs as $k => $va) {
            $config[$va['name']] = $va['value'];
        }
        unset($configs);

        // 获取配置后校验开关
        if ($config['switch']) {

            $name = [1=>'first_leader',2=>'second_leader', 3=>'third_leader', 4=>'fourth_leader'];
            $ratio = $config[$name[$num]];

            // 当前设置值有效 执行分销奖项
            if ($ratio >0) {
                Db::startTrans();

                $profit = $minerInfo['miner'] * $ratio;
                $afterMiner = $leader['miner'] + $profit;

                $userRes = Db::name('member')->where(['id' => $user_id])->update(['miner' => $afterMiner]);
                $logRes = minerlog($minerInfo['id'], $leader['id'], $profit, 6, $leader['miner'],$afterMiner,'分销奖励');
                if ($userRes && $logRes) {
                    Db::commit();
                } else {
                    Db::rollback();
                }
            }
        }
        if ($leader['parentId']) {
            $num++;
            $this->distribut($leader['parentId'], $minerInfo,$num);
        }

    }

    /**
     * 获取用户算力值
     *
     * 算力值来源：自己所有渔船获得 + 无限层内每个人拥有最高级别
     */
    public function getCalculation($user_id)
    {
        // 自己总算力值
        $user = Db::name('member')->field('all_calculation,give_calculation,parentId')->find($user_id);

        return $user['all_calculation'] + $user['give_calculation'];
    }

    /**
     * 获取团队人数
     * @param  $user_id    用户id
     * @param  $accumulate 人数累积值
     * @return 返回最后团队人数
     */
    public function getTeam($path)
    {
        $count = Db::name('member')->where(['path' => ['like', $path.'%'], 'isReal' => 1])->count();

        return $count;
    }


    /**
     * 领取收益
     * @param  $miner 渔船信息
     * @return        收益情况
     */
    public function porfit($miner)
    {
        if ($miner['status'] != 1) {
            return false;
        }
        if ($miner['is_start'] != 1) {
            return false;
        }
        //查询用户信息
        $user = Db::name('member')->field('miner,id,parentId,kj_all_token,level,all_receive')->where(['id' => $miner['user_id']])->find();
        //矿机收益 = 矿机token * 矿机生产速度
        if ($user['all_receive'] >= $miner['miner_price']){
            //收益等于实际投资金额，降低为千分之五
            $kj_tokem_speed = $miner['kj_token_speed'] / 100 * 0.5;
        }else{
            //收益不等，按正常速度
            $kj_tokem_speed = $miner['kj_token_speed']/100;
        }
        $profit = $miner['miner_price'] * $kj_tokem_speed;  //矿机收益
        //用户购买矿机剩余token
        $after_kj_token= $miner['kj_token'] - $profit;
        $kjData = [];
        if ($after_kj_token <= 0){
            if ($miner['kj_pre_token'] > 0){
                $upData = [
                    'kj_token' => $miner['kj_token'] + $miner['kj_pre_token'],
                    'kj_pre_token' => 0
                ];
                Db::name('user_miner')->where(['id' => $miner['id']])->save($upData);
                $upData2 = [
                    'kj_all_token' => $user['kj_all_token'] + $miner['kj_pre_token']
                ];
                Db::name('member')->where(['id' => $miner['user_id']])->save($upData2);
                $miner = Db::name('user_miner')->where('id', $miner['id'])->find();
                $after_kj_token = $miner['kj_token'] - $profit;
            }else{
                $after_kj_token = 0;
                $kjData['status'] = 2;
            }
        }
        $user = Db::name('member')->field('miner,id,parentId,kj_all_token,level,all_receive')->where(['id' => $miner['user_id']])->find();
        //用户购买矿机已产token
        $kj_already_token = $miner['kj_already_token'] + $profit;
        //矿机数据
        $kjData['kj_token'] = $after_kj_token;
        $kjData['kj_already_token'] = $kj_already_token;
        $kjData['receive'] = $miner['receive'] + $profit;
        $kjData['receive_time'] = time();
        //用户数据
        $userData = [
            'kj_all_token' => ($user['kj_all_token'] - $profit) < 0 ? 0 : ($user['kj_all_token'] - $profit),
            'miner' => $user['miner'] + $profit,
            'all_receive' => $user['all_receive'] + $profit
        ];
        $profitData = [
            'user_id' => $miner['user_id'],
            'miner_id' => $miner['id'],
            'profit' => $profit,
            'times' => 24,
            'add_time' => time(),
            'after_miner_receive' =>$kj_already_token
        ];
        $profitRes = Db::name('miner_profit')->insertGetId($profitData);
        //更新用户购买矿机数据
        $minerRes = Db::name('user_miner')->where(['id' => $miner['id']])->save($kjData);
        //添加记录
        $logRes = minerlog($profitRes, $miner['user_id'], $profit, 6, $user['miner'], $userData['miner'], '矿机收益');
        //更新用户数据
        $userRes = Db::name('member')->where(['id' => $miner['user_id']])->save($userData);
        if ($minerRes && $logRes && $profitRes && $userRes) {
            //计算上级收益
            if ($user['parentId']) {
                $this->distribuParent($user['parentId'], $profit, $miner['id']);
            }
            return true;
        }
        return false;
    }

    /**
     * 查询该用户是否满足联合创始人
     * 1.直推会员满足3个三星会员
     * 2.增加0.001
     * */
    public function isLhSpeed($user_id){
        $count = Db::name('member')
            ->field('id,parentId,level')
            ->where(['parentId' => $user_id,'level'=>4])->count();
        if ($count >= 3){
            return 0.001;
        }else{
            return 0;
        }
    }

    /**
     * 用户升级
     * @param  $user_id 升级用户ID
     * @param  $miner   渔船信息
     * @return          升级状况
     */
    public function updateLevel($user_id,$miner)
    {
        $levelInfo = Db::name('world_level')->field('level_id,up_condition')->order('level_id desc')->select();
        $user = Db::name('member')->field('level,all_calculation,give_calculation,account,id')->where(['id' => $user_id])->find();
        foreach ($levelInfo as $k => $va) {
            if ($va['level_id'] <=2) {
                return false;
            }
            $up_condition = unserialize($va['up_condition']);
            if ($user['level'] >= $va['level_id']) {
                return true;
            }
            $calculation = $this->getTeamCalculation($user_id);
            // 算力值 不符合
            if ($up_condition['one']['miner_number'] > ($user['all_calculation'] + $user['give_calculation'])) {
                continue;
            }
            $count = Db::name('user_miner')->where(['user_id' =>$user_id, 'miner_id' =>$up_condition['two']['miner_id']])->count();
            if ($up_condition['two']['miner_number'] >$count) {
                continue;
            }
            // 等级符合  算力值符合  渔船数目符合 升级

            // 升级记录
            $levelData = [
                'user_id' => $user_id,
                'account' => $user['account'],
                'desc' => '购买渔船升级',
                'before_level' => $user['level'],
                'after_level' => $va['level_id'],
                'type' => 2,
                'change_time' => time(),
            ];
            Db::startTrans();
            $levelLogRes = Db::name('vpay_level_log')->insertGetId($levelData);
            $userRes = Db::name('member')->where(['id' => $user_id])->update(['level' => $va['level_id']]);
            if ($levelLogRes && $userRes) {
                Db::commit();
                $this->reflectId = $levelLogRes;
                $this->updateLevelPrize($user_id, $levelData);
                return true;
            } else {
                Db::rollback();
                return false;
            }
        }
    }

    /**
     * 升级奖励
     * @param   $user_id 升级用户ID
     * @param   $data    升级前后信息
     * @return           升级状况
     */
    public function updateLevelPrize($user_id,$data)
    {
        $give_money = $this->getPrize($data);
        if ($give_money > 0) {
            Db::startTrans();
            $miner_pool = Db::name('member')->where(['id' => $user_id])->value('miner_pool');
            $after_pool = $miner_pool + $give_money;
            $logRes = miner_poollog($this->reflectId, $user_id, $give_money, 3, $miner_pool,$after_pool,'升级奖励');
            $userRes = Db::name('member')->where(['id' => $user_id])->update(['miner_pool' => $after_pool]);
            if ($logRes && $userRes) {
                Db::commit();
                return true;
            } else {
                Db::rollback();
                return false;
            }
        }
    }

    /**
     * 根据升级前后等级  获取奖励金额
     * @param  $data 升级前后等级信息
     * @return       奖励金额
     */
    private function getPrize($data)
    {
        if (!$data['before_level'] || !$data['after_level']) {
            return false;
        }

        $accumulate = 0;
        for ($i=$data['after_level']; $i > $data['before_level']; $i--) {
            $config = distributCache('updateLevel-'.$i);
            $configs = Db::name('distribut_system')->field('name,value')->where(['level_id' => $i, 'name' => ['in', 'switch,give_money']])->select();
            foreach ($configs as $key => $va) {
                $config[$va['name']] = $va['value'];
            }
            unset($configsf);
            if ($config['switch']) {
                $accumulate += $config['give_money'];
            }
        }

        return $accumulate;
    }

    /**
     * 获取无限层最高算力值
     * @param  $user_id    用户id
     * @param  $accumulate 累积算力值
     * @return 返回最后累积算力值
     */
    private function getTeamCalculation($user_id,$accumulate = 0)
    {
        $first_leader = Db::name('member')->field('give_calculation,parentId')->find($user_id);

        // 存在上级 没被删除
        if ($first_leader) {
            // 累计
            $accumulate += $first_leader['give_calculation'];
            if ($first_leader['parentId']) {
                $this->getTeamCalculation($first_leader['parentId'], $accumulate);
            }
        }
        //  不存在上级信息  返回当前累积值
        return $accumulate;
    }

    /**
     * 获取订单 order_sn
     * @return string
     */
    public function getMinerSn()
    {
        $order_sn = null;
        // 保证不会有重复订单号存在
        while (true) {
            $order_sn = 'LX'.date('YmdHis'); // 订单编号
            $order_sn_count = M('user_miner')->where(['sn'=>$order_sn])->count();
            if ($order_sn_count == 0)
                break;
        }
        return $order_sn;
    }
}
